/**
 * 遍历所有文件夹并将中文替换为对应函数
 */

const fs = require("fs");
const path = require("path");
const parser = require("@babel/parser"); // 解析为ast
const traverse2 = require("@babel/traverse"); // 遍历ast
const path2 = require("path");
const t = require("@babel/types"); // 创建ast语法结构
const generator2 = require("@babel/generator"); // 转义ast 生成文件结果
const { glob } = require("glob"); // 遍历文件依赖
const chalk = require("chalk"); // 打印

// const {chineseReg} = require('./intl-trans/contants')
const { haveChineseChart, createHashCode, ignoreFun } = require("./utils");
const { createMessage } = require("./createMessages");

const traverse = traverse2.default;
const generator = generator2.default;

const commonArgs = {};

commonArgs["impFuncs"] = "T";
// 遍历目录函数
async function traverseDirectory(dir, callback) {
  const files = await glob("**/*.js", {
    cwd: dir,
    ignore: ["messages.js", "node.js"],
  });
  let full_map = new Map();
  try {
    // console.log('file',files)
    files.forEach((file) => {
      const [map, modifyMap] = callback(path.join(dir, file));
      // console.log('map', map);
      full_map = new Map([...full_map, ...map, ...modifyMap]);
    });
    // console.log('full_map', full_map);
    createMessage({
      full_map,
      dir,
    });
  } catch (err) {
    console.log("err", err);
  }
}

// 替换函数
function replaceTextInFile(filePath) {
  const prettierConfig = path.resolve(__dirname, "./") || {};
  // 将生成的内容存入map
  const newMap = new Map();
  const modifyMap = new Map();
  let modified = 0;

  function createHash(value, options = {}) {
    const { notSetMap = false } = options;
    const hash = createHashCode(value, filePath);
    if (!notSetMap) {
      newMap.set(hash, value);
    }

    return hash;
  }
  try {
    const data = fs.readFileSync(filePath, "utf8");

    // parser 解析为ast结构
    const astCode = parser.parse(data, {
      sourceType: "module",
      plugins: [
        // enable jsx and flow syntax
        "jsx",
        // "flow",
      ],
    });

    traverse(astCode, {
      enter(path, state) {
        path.node.value && console.log("path-type", path.type, path.node.value);
      },
      JSXText(path, state) {
        // 处理text类型
        const value = path.node.value.replace(/[\n ]+/, "");
        // const value = path.node.value;
        if (haveChineseChart(value)) {
          // 含有中文
          // console.log(`JSXText-path${index}-纯中文-----------`, value);
          const hash = createHash(value);

          path.replaceWith(
            t.jsxExpressionContainer(
              t.callExpression(t.identifier(commonArgs["impFuncs"]), [
                t.stringLiteral(value),
                t.stringLiteral(hash),
              ])
            )
          );
        }
      },
      JSXAttribute(path) {
        // console.log('JSXAttribute-path',path)
        // jsx属性- name是JSXIdentifier标识符类型 并且内容是string
        if (t.isJSXAttribute(path.node)) {
          if (
            t.isJSXIdentifier(path.node.name) &&
            t.isStringLiteral(path.node.value)
          ) {
            const value = path.node.value.value;
            if (haveChineseChart(value)) {
              const hash = createHash(value);
              path.replaceWith(
                t.jsxAttribute(
                  t.jsxIdentifier(path.node.name.name),
                  t.jsxExpressionContainer(
                    t.callExpression(t.identifier(commonArgs["impFuncs"]), [
                      t.stringLiteral(value),
                      t.stringLiteral(hash),
                    ])
                  )
                )
              );
            }
          }
        }
      },
    });

    traverse(astCode, {
      StringLiteral(path, state) {
        // 节点内的描述
        const value = path.node.value.replace(/[\n ]+/, "");

        // console.log('path.node',path)
        if (haveChineseChart(value)) {
          if (ignoreFun.isConsole(path)) {
            return;
          }
          if (
            t.isCallExpression(path.parent) &&
            t.isIdentifier(path.parent.callee)
          ) {
            // todo  这里做校验，判断文案和hash是否相同
            if (path.parent.callee.name === commonArgs["impFuncs"]) {
              // 如果是在console里  不做处理
            } else {
            }
          } else {
            if (haveChineseChart(value)) {
              // 含有中文
              const hash = createHash(value);
              // const hash = createHashCode(value);
              path.replaceWith(
                // t.jsxExpressionContainer(
                t.callExpression(t.identifier(commonArgs["impFuncs"]), [
                  t.stringLiteral(value),
                  t.stringLiteral(hash),
                ])
                // ),
              );
            }
          }
        }
        // console.log(`StringLiteral-path${index}`,value)
      },
      TemplateLiteral(path) {
        // `修改${a}含有变量格式文本`
        const quasis = path.node.quasis; // 所有文本描述
        const expressions = path.node.expressions; // 所有参数变量

        let str = "";
        const stringsList = [];
        for (let i = 0; i < quasis.length; i++) {
          const element = quasis[i].value.raw;
          stringsList.push(element);
          if (i < expressions.length) {
            stringsList.push(`{${expressions[i]?.loc?.identifierName ?? i}}`);
          }
        }
        str = stringsList.join("");
        if (!haveChineseChart(str)) {
          return path.skip();
        }
        const hash = createHash(str);
        const a = t.objectExpression(
          expressions.map((item, index) => {
            return t.objectProperty(
              t.identifier(`${item.loc.identifierName ?? index}`),
              item,
              false,
              true
            );
          })
        );
        const codes = t.callExpression(t.identifier(commonArgs["impFuncs"]), [
          t.stringLiteral(str),
          t.stringLiteral(hash),
          a,
        ]);
        try {
          path.replaceWith(codes);
        } catch (err) {
          return path.skip();
        }
      },
    });

    traverse(astCode, {
      CallExpression(path, state) {
        // 含有参数的描述
        const calleeName = path.node.callee.name;
        if (path.node.callee.name === commonArgs["impFuncs"]) {
          // 如果函数名称是 commonArgs['impFuncs'])的
          // 判断内容是否有变化
          const value = path.node.arguments[0].value;
          // 之前hash
          const oldHash = path.node.arguments[1].value;
          // 新生成hash
          const newHash = createHash(value, { notSetMap: true });
          if (oldHash !== newHash) {
            modifyMap.set(newHash, value);
            console.log("modified-----", value);
            modified++;
            if (path.node.arguments.length > 2) {
              path.replaceWith(
                t.callExpression(t.identifier(commonArgs["impFuncs"]), [
                  t.stringLiteral(value),
                  t.stringLiteral(newHash),
                  ...path.node.arguments.slice(2),
                ])
              );
            } else {
              path.replaceWith(
                t.callExpression(t.identifier(commonArgs["impFuncs"]), [
                  t.stringLiteral(value),
                  t.stringLiteral(newHash),
                ])
              );
            }
          } else {
            newMap.set(newHash, value);
          }
        }
        // console.log(`TemplateElement-path${1}`, value);
        // console.log(`TemplateElement-path${index}`,path)
      },
    });
    let foundImport = false;
    traverse(astCode, {
      ImportDeclaration(path) {
        const node = path.node;
        if (node.source.value === "base/intl") {
          // 检查导入来源是否匹配
          const specifiers = node.specifiers;
          for (let i = 0; i < specifiers.length; i++) {
            const specifier = specifiers[i];
            if (specifier.imported && specifier.imported.name === "T") {
              // 检查导入的标识符是否匹配
              foundImport = true;
              break;
            }
          }
        }
      },
    });

    if (!foundImport) {
      console.log('The specific import statement was not found. Adding it.');
    
      // 创建新的 import 语句节点
      const newImport = "import {T} from 'base/intl';";
    
      // 将新导入语句作为字符串解析成 AST 节点
      const newImportAst = parser.parse(newImport, { sourceType: 'module' }).program.body[0];
    
      // 插入到现有 AST 的最前面
      astCode.program.body.unshift(newImportAst);
    
      console.log('New import statement has been added.');
    } else {
      console.log('Found the specific import statement.');
    }
    // console.log("astCode", astCode);
          // 使用 Babel generator 将修改后的 AST 转换回源代码
    const newAstCode = generator(astCode, {
      retainLines: true,
      jsescOption: {
        minimal: true,
      },
      printWidth: 100,
      tabWidth: 2,
      useTabs: false,
      semi: true,
      singleQuote: true,
      trailingComma: "all",
      endOfLine: "auto",
    }).code;

          // 写回到文件系统
    fs.writeFileSync(filePath, newAstCode, "utf-8");
    // return;
  } catch (error) {
    console.log("error", error);
  }

  // console.log('newMap', newMap);
  // 生成
  return [newMap, modifyMap];
}

function main() {
  const directory = process.argv[2]; // 文件目录
  // console.log(arg1)
  // 主执行逻辑
  // const directory = './model/intlMock'; // 更改为你的目标目录
  try {
    const stats = fs.statSync(directory);
    // console.log(stats.isFile())
    // 判读是否为文件夹
    if (!stats.isDirectory()) {
      console.error(chalk.red("error---请输入正确的文件夹地址"));
      return;
    }

    traverseDirectory(directory, replaceTextInFile);
  } catch (err) {
    if (err.code === "ENOENT") {
      console.error(chalk.red(`路径 ${directory} 不存在`));
    } else {
      console.error(`发生错误: ${err.message}`);
    }
  }
}

main();
